package com.spring.framework.ioc.bean.post;

import com.spring.framework.model.learn.Address;
import com.spring.framework.model.learn.School;
import com.spring.framework.model.learn.Student;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

/**
 * BeanDefinition 加载阶段,可以注册 BeanDefinition 信息
 *
 * @author xuweizhi
 * @since 2020/12/04 21:50
 */
@Component
public class CustomizeBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

	/**
	 * 调用我们的后置处理器{@link org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors}
	 * <p>
	 * 大概在 175 行
	 */
	@Override
	@SuppressWarnings("all")
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		// 获得bean定义i
		RootBeanDefinition student = (RootBeanDefinition) beanFactory.getBeanDefinition("student");

		// 修改Class
		//student.setBeanClass(Tank.class);

		//设置默认值 相当于xml:<property name = "school" value = "徐庶" / >
		student.getPropertyValues().addPropertyValue(new PropertyValue("school", new School("学校", new Address())));

		//设置构造函数 相当于xml:<constructor - arg index = "0" value = "徐庶" / >
		//student.getConstructorArgumentValues().addIndexedArgumentValue(0, "徐庶2");

		//自动装配方式
		//student.setAutowireMode(AUTOWIRE_BY_NAME);

		//强制依赖检查：
		//student.setDependencyCheck(AbstractBeanDefinition.DEPENDENCY_CHECK_ALL);
		student.setLazyInit(true);

		student.setInitMethodName("initMethod");
	}

	/**
	 * 调用我们的后置处理器{@link org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors}
	 * <p>
	 * 大概在 167 行
	 */
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		RootBeanDefinition student = new RootBeanDefinition();
		student.setBeanClass(Student.class);
		registry.registerBeanDefinition("student", student);
	}
}
